package hotel.meituan.oversea.biz.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.enums.MtHotelEnums;
import hotel.base.oversea.utils.*;
import hotel.meituan.oversea.api.entity.MtHotelOrderStateHistory;
import hotel.meituan.oversea.api.vo.down.request.order.MtHotelOrderJobQueryOrderVo;
import hotel.meituan.oversea.biz.config.service.RedisService;
import hotel.meituan.oversea.biz.mapper.MtHotelGoodsInfoNotifyLogMapper;
import hotel.meituan.oversea.biz.mapper.MtHotelGoodsStatusNotifyLogMapper;
import hotel.meituan.oversea.biz.mapper.MtNotifyShortLogMapper;
import hotel.meituan.oversea.biz.service.MtHotelOrderService;
import hotel.meituan.oversea.biz.service.MtHotelService;
import hotel.meituan.oversea.biz.task.MeituanSaveUpdateGoodsPriceTableTask;
import hotel.meituan.oversea.biz.task.MeituanSaveUpdateGoodsStatusTableOtherTask;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 美团酒店信息Controller
 * @author qiuyy
 * @date 2020-05-15
 */
@Slf4j
@RestController
@RequestMapping("/mtHotelOrderNotify")
@Api(value = "MtHotelOrderNotifyController", tags = {"美团酒店订单接口"})
public class MtHotelOrderNotifyController {
    @Autowired
    private MtHotelGoodsInfoNotifyLogMapper mtHotelGoodsInfoNotifyLogMapper;
    @Autowired
    private MtHotelGoodsStatusNotifyLogMapper mtHotelGoodsStatusNotifyLogMapper;
    @Autowired
    private MtNotifyShortLogMapper mtNotifyShortLogMapper;
    @Autowired
    private MeituanSaveUpdateGoodsStatusTableOtherTask meituanSaveUpdateGoodsStatusTableOtherTask;

    @Autowired
    private MtHotelOrderService mtHotelOrderService;

    @Autowired
    private MtHotelService mtHotelService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RedisService redisService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MeituanSaveUpdateGoodsPriceTableTask meituanSaveUpdateGoodsPriceTableTask;



    /**
     * 发送钉钉消息通知
     */
    public void requestSendDingMessage(String title,String data){
        SendUtils.dingMsg(title,data,99,restTemplate);
    }

    @PostMapping("/orderCallback")
    @ApiOperation(value = "订单消息通知",notes="必须经过auth授权")
    public ResultMt<Object> checkOrder(HttpServletRequest request){
        //正常来说，下单待确认的订单和申请了订单取消的订单，才需要异步通知；

        Map map = getDataRequest(request);
        log.info("/////////////////////////////订单异步通知    :"+ JSON.toJSONString(map));
        if(null != map && map.size()>0){
            String method = (String)map.get("method");
            if(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_STATE_CALLBACK.getMethod().equals(method)){
                String dataStr = (String)map.get("data");
                Map<String,Object> date = JSONObject.parseObject(dataStr,Map.class);//(Map)map.get("data");

                /**
                 * 订单状态orderStatus：
                 * 21 预订成功 book_suc
                 * 22 预订失败 book_fail
                 * 31 取消成功 cancel_suc
                 * 40 美团客服介入退款 abort
                 * 50 已入住 book_checkin
                 */
                //保存日志
                Integer orderStatus = (Integer)date.get("orderStatus");
                String mtOrderId = String.valueOf(date.get("mtOrderId"));
                String distributorOrderId_index = (String)date.get("distributorOrderId");
                /*if(distributorOrderId_index.substring(0,2).equals(ChannelEnums.Head.ORDER_HEAD_FP.getCode())){
                    //飞猪美团订单号,推给渠道系统
                    remoteChannelService.mtCallbackOrderStatus(GsonUtils.GsonString(map));
                }else{
                    //保存日志
                    MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                    stateHistory.setMtDistributorOrderId(distributorOrderId_index);
                    stateHistory.setSwOrderId(distributorOrderId_index.substring(0,distributorOrderId_index.length()-3));
                    stateHistory.setMtOrderId(mtOrderId);
                    stateHistory.setStatusCode(orderStatus);
                    stateHistory.setStatusDesc((String)date.get("desc"));
                    stateHistory.setMtHotelId(null);
                    stateHistory.setMtGoodsId(null);
                    stateHistory.setMethod(method);
                    stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_STATE_CALLBACK.getName());
                    stateHistory.setClassJson(JSON.toJSONString(map));
                    stateHistory.setMtOrderState(orderStatus);

                    MtHotelOrderJobQueryOrderVo mtHotelOrderJobQueryOrderVo = new MtHotelOrderJobQueryOrderVo();
                    mtHotelOrderJobQueryOrderVo.setOrderStatus(orderStatus);
                    mtHotelOrderJobQueryOrderVo.setDistributorOrderId(distributorOrderId_index);
                    mtHotelOrderJobQueryOrderVo.setMtOrderId(mtOrderId);
                    requestCheckOneOrderMtNotice(mtHotelOrderJobQueryOrderVo,stateHistory);
                }*/

                //保存日志
                MtHotelOrderStateHistory stateHistory = new MtHotelOrderStateHistory();
                stateHistory.setMtDistributorOrderId(distributorOrderId_index);
                stateHistory.setSwOrderId(distributorOrderId_index.substring(0,distributorOrderId_index.length()-3));
                stateHistory.setMtOrderId(mtOrderId);
                stateHistory.setStatusCode(orderStatus);
                stateHistory.setStatusDesc((String)date.get("desc"));
                stateHistory.setMtHotelId(null);
                stateHistory.setMtGoodsId(null);
                stateHistory.setMethod(method);
                stateHistory.setMethodName(MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ORDER_STATE_CALLBACK.getName());
                stateHistory.setClassJson(JSON.toJSONString(map));
                stateHistory.setMtOrderState(orderStatus);

                MtHotelOrderJobQueryOrderVo mtHotelOrderJobQueryOrderVo = new MtHotelOrderJobQueryOrderVo();
                mtHotelOrderJobQueryOrderVo.setOrderStatus(orderStatus);
                mtHotelOrderJobQueryOrderVo.setDistributorOrderId(distributorOrderId_index);
                mtHotelOrderJobQueryOrderVo.setMtOrderId(mtOrderId);
                requestCheckOneOrderMtNotice(mtHotelOrderJobQueryOrderVo,stateHistory);
//
            }else{
                log.error("/////////////////  orderCallback 订单状态通知接收异常，上游method不匹配，需立即排查 ：{},{}",System.currentTimeMillis(), JSON.toJSONString(map));
                return new ResultMt<>("method error",-1);
            }

        }else{
            log.error("/////////////////  orderCallback 订单状态通知接收异常，请求参数为空");
            return new ResultMt<>("请求参数为空",-1);
        }
        return new ResultMt();
    }

    /**
     * 异步通知的订单进行分析更新
     *
     * 定时器订单主动查询也是ORDER_CHECK_UPDATE，两边调用；所以主动查询频率不能高最低30秒一次
     *
     * @param mtHotelOrderJobQueryOrderVo
     * @param stateHistory
     * @return
     */
    public boolean requestCheckOneOrderMtNotice(MtHotelOrderJobQueryOrderVo mtHotelOrderJobQueryOrderVo, MtHotelOrderStateHistory stateHistory) {
        log.info("/////////////////  orderCallback 订单状态通知接收，requestCheckOneOrderMtNotice 进入",System.currentTimeMillis());
        Result result = mtHotelOrderService.jobQueryOrderCheckSave(mtHotelOrderJobQueryOrderVo,stateHistory," orderCallback 美团订单异步通知 ");
        if(result.getCode() == CommonConstants.SUCCESS){
            return true;//返回给美团 0
        }else{
            log.info("{} orderCallback 美团异步通知 请求内部处理接口 jobQueryOrderCheckSave 请求失败：{}",result);
        }
        return false;//返回给美团 -1
    }


    /**
     * result内容为单层数据，返回map，key value获取数据
     * @param request
     * @return
     */
    private Map<String,Object> getDataRequest(HttpServletRequest request){
        String type = request.getContentType();
        Map<String,Object> receiveMap = new HashMap<>();
        if("application/x-www-form-urlencoded".equals(type)){
            Enumeration<String> enu = request.getParameterNames();
            while (enu.hasMoreElements()) {
                String key = String.valueOf(enu.nextElement());
                String value = request.getParameter(key);
                receiveMap.put(key, value);
            }
        }else{	//else是text/plain、application/json这两种情况
            BufferedReader reader = null;
            StringBuilder sb = new StringBuilder();
            try{
                reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
                String line = null;
                while ((line = reader.readLine()) != null){
                    sb.append(line);
                }
            } catch (IOException e){
                e.printStackTrace();
            } finally {
                try{
                    if (null != reader){
                        reader.close();
                    }
                } catch (IOException e){
                    e.printStackTrace();
                }
            }
            String str = sb.toString();
            if(!StringUtils.isEmpty(str)){
                receiveMap = JSON.parseObject(str,Map.class);
            }
        }
        return receiveMap;
    }
    /**
     * result内容为多层数据集合，返回str，外部parse对象获取数据
     * @param request
     * @return
     */
    private String getStrRequest(HttpServletRequest request){
        String type = request.getContentType();
        Map<String,Object> receiveMap = new HashMap<>();
        if("application/x-www-form-urlencoded".equals(type)){
            Enumeration<String> enu = request.getParameterNames();
            while (enu.hasMoreElements()) {
                String key = String.valueOf(enu.nextElement());
                String value = request.getParameter(key);
                receiveMap.put(key, value);
                return JSON.toJSONString(receiveMap);
            }
        }else{	//else是text/plain、application/json这两种情况
            BufferedReader reader = null;
            StringBuilder sb = new StringBuilder();
            try{
                reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
                String line = null;
                while ((line = reader.readLine()) != null){
                    sb.append(line);
                }
            } catch (IOException e){
                e.printStackTrace();
            } finally {
                try{
                    if (null != reader){
                        reader.close();
                    }
                } catch (IOException e){
                    e.printStackTrace();
                }
            }
            String str = sb.toString();
            return str;
        }
        return null;
    }

}
